//! Header for the Picutre class
/*!
	\file Picture.h
	\author Thomas Pfeiffer
	\date 13.11.2012
*/
#ifndef PICTURE_H
#define PICTURE_H

#include <list>
#include <string>

#include "Object.h"
#include "Shape.h"
#include "IShapeFactory.h"

//! Able to manage Shapes and save/load them to/from a file
/*!
\class Picture
The class Picture manages a list of shapes. A Picture offers functions
to add circles and shapes to the list of managed shapes. Once a shape is added,
it can't be removed again.
*/
class Picture : public Object {
public:
	
	//! DTor of the Picture
	/*!
	Frees the memory used by the managed shapes
	*/
	~Picture();

	//! CTor of the Picture
	/*!
	The constructor of the Picture takes two parameters. It initializes
	the filename which can only be set when constructing the picture and
	it sets the Factory of the picture which also can't be changed during
	runtime.
	\param filename The filename where the picture stores its shapes
	\param fact A Pointer to a Factory. Currently there're a Filled- and a
	            Transparent- ShapeFactory.
	*/
	// string isn't being passed by ref (const&) because i want to store a copy of it.
	Picture(std::string filename, IShapeFactory * fact);

	//! Saves the image to its associated file
	/*!
	Writes all the Shapes which are managed by the picture to their corresponding file.
	*/
	void WriteSVG() const;

	//! Loads Shapes from a file (to initialize a picture)
	/*!
	Reads the file filename which must be a file structured like it's described
	in the system documentation to initialize the picture with shapes.
	\param filename The Filename of the file which holds the shapes.
	\throws std::exception if the file wasn't found or couldn't be opened and if the
	file has a wrong format.
	*/
	void LoadShapes(std::string const& filename);

	//! Adds a circle to the picture
	/*!
	The function AddCircle() adds a Circle to the list of Shapes managed by
	the picture. Depending on the Factory the picture has, the circle is
	filled or transparent.
	\param origin Position where the center of the circle should be
	\param radius The radius of the circle
	\param color The color which the stroke or the filling of the circle
	             should have. If the string is empty, or the color is 
				 not recognized, it's changed to black.
	\throws std::exception if the file wasn't found or couldn't be opened.
	*/
	void AddCircle(TPosition const& origin, float const& radius, std::string const& color);
	
	//! Adds a rectangle to the picture
	/*!
	The function AddRectangle() adds a rectangle to the list of Shapes managed by
	the picture. Depending on the Factory the picture has, the rectangle is
	filled or transparent.
	\param origin Position where the upper left corner of the rectangle should be
	\param dimension The height and the width of the rectangle
	\param color The color which the stroke or the filling of the rectangle
	             should have. If the string is empty, or the color is 
				 not recognized, it's changed to black.
	*/
	void AddRectangle(TPosition const& origin, TSize const& dimension, std::string const& color);

	//! Returns the associated Filename of the picture
	std::string const& getFileName() const;

private:
	// pictures shouldn't be copied or assigned
	// because their shapes can't either
	Picture (Picture const& pic);
	Picture & operator=(Picture const& p);

	typedef std::list<Shape*> TShapes;
	typedef TShapes::const_iterator TShapesConstIterator;

	IShapeFactory * mShapeFactory; 
	TShapes mShapes;
	std::string mFilename;

	// checks if the next char of ifs is
	// a | .
	// throws and exception if not
	void checkSep(std::ifstream & ifs);

	// Returns the Factory of the picture
	IShapeFactory * getFactory() const;
	
	// static variables which define constant strings
	// initialized in the cpp file
	static const std::string XML_HEADER;
	static const std::string SVG_HEADER;
	static const std::string XML_FOOTER;
};	

#endif